package cn.redragon.soa.common.function;

import static org.springframework.util.StringUtils.hasText;

import cn.redragon.soa.common.service.RedisService;
import cn.redragon.soa.common.util.JsonUtil;
import java.util.Collection;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
import org.apache.commons.collections4.CollectionUtils;

public class RedisHashFunction<T> extends RedisFunction<T> {

    private String hashField;

    public RedisHashFunction(Class<T> tClass, RedisService redisService) {
        super(tClass, redisService);
    }

    public static <T> RedisHashFunction<T> with(Class<T> tClass, RedisService redisService) {
        Objects.requireNonNull(redisService);
        return new RedisHashFunction<>(tClass, redisService);
    }

    @Override
    public RedisHashFunction<T> cacheKey(String cacheKey) {
        this.cacheKey = cacheKey;
        return this;
    }

    @Override
    public RedisHashFunction<T> ttl(Long ttl) {
        this.ttl = ttl;
        return this;
    }

    public RedisHashFunction<T> hashField(String hashField) {
        this.hashField = hashField;
        return this;
    }

    @Override
    protected <R> R get(Supplier<R> supplier, Function<String, R> function) {
        String value = redisService.hashGet(cacheKey, hashField);
        if (hasText(value)) {
            return function.apply(value);
        }
        R s = supplier.get();
        if (s == null && !allowNullValue) {
            return null;
        }
        if (s != null && !allowNullValue && Collection.class.isAssignableFrom(s.getClass()) && CollectionUtils.isEmpty((Collection<?>) s)) {
            return s;
        }

        redisService.hashSet(cacheKey, hashField, JsonUtil.objectToJsonStrNullable(s));
        if (ttl != null) {
            redisService.expire(cacheKey, ttl, TimeUnit.SECONDS);
        }

        return s;
    }
}
